import paramiko
import time, os, json,re
from Logger import logger


# def ssh_connect(ip, username, password):
#     # 创建SSH客户端
#     client = paramiko.SSHClient()
#     # 自动添加远程服务器的主机密钥
#     client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#     # 连接SSH服务器
#     client.connect(ip, username=username, password=password)
#     return client
def ssh_connect(ip, username, password):
    try:
        # 创建SSH客户端
        client = paramiko.SSHClient()
        # 自动添加远程服务器的主机密钥
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # 连接SSH服务器
        client.connect(ip, username=username, password=password)
        # 关闭SSH连接
        client.close()
        return True, None
    except paramiko.AuthenticationException as e:
        return False, "认证失败，请检查用户名和密码是否正确。"
    except paramiko.SSHException as e:
        return False, "SSH连接失败，请检查主机IP地址是否正确或SSH服务是否开启。"
    except Exception as e:
        return False, str(e)


def execute_command_linux(client, command):
    # 执行命令
    _, stdout, stderr = client.exec_command(command)
    output = stdout.read().decode('utf-8')
    error = stderr.read().decode('utf-8')
    if error:
        logger.info(f'执行命令时发生错误：{error}')
    else:
        logger.info(f'{command},执行成功')
    return output


def check_jdk_installed(ip, username, password):
    # 远程连接
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_client.connect(ip, username=username, password=password)

    # 关闭防火墙
    execute_command_linux(ssh_client, 'bash -l -c "systemctl stop firewalld"')
    execute_command_linux(ssh_client, 'bash -l -c "service iptables stop"')

    # 检查JDK是否已安装
    _, stdout, stderr = ssh_client.exec_command('bash -l -c "java -version"')
    output = stdout.read().decode('utf-8')
    error = stderr.read().decode('utf-8')
    error_info = error.lower().strip()
    if 'java version' in error_info:
        logger.info('JDK已安装')
        jdk_statue = 1
    else:
        logger.info(f'JDK未安装,错误信息：{error}', )
        logger.info('<——————开始安装JDK——————>')
        result = install_jdk(ssh_client)
        if result == 0:
            logger.info('<——————JDK已安装完毕——————>')
            jdk_statue = 1
        else:
            logger.info('JDK安装失败！')
            jdk_statue = 0
    return jdk_statue

    # 关闭SSH连接
    ssh_client.close()


def install_jdk(client):
    # 检查操作系统类型，暂时只支持Linux
    output = execute_command_linux(client, 'uname')
    os_type = output.strip()
    logger.info(os_type)

    if os_type == 'Linux':
        # 传输JDK安装包到远程机器
        PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 根目录
        jdk_local_path = os.path.join(PROJECT_ROOT, 'backend\static\jdk\jdk-8u212-linux-x64.tar.gz')  # 替换为本地JDK安装包路径
        jdk_remote_path = '/home/jdk-8u212-linux-x64.tar.gz'  # 替换为远程机器上的JDK安装包路径

        sftp = client.open_sftp()
        sftp.put(jdk_local_path, jdk_remote_path)
        sftp.close()

        # 解压JDK安装包
        execute_command_linux(client, f'tar -zxvf {jdk_remote_path} -C /home')

        # 设置环境变量
        commands = [
            "sed -i '/export JAVA_HOME/d' /etc/profile",
            'echo "export JAVA_HOME=/home/jdk1.8.0_212" >> /etc/profile',
            'echo "export PATH=\\"$PATH:\\$JAVA_HOME/bin\\"" >> /etc/profile',
            'source /etc/profile'
        ]

        for command in commands:
            execute_command_linux(client, command)
    return 0


def install_jmeter(ip, username, password, xms, xmx):
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_client.connect(ip, username=username, password=password)

    # 检查操作系统类型，当前仅支持Linux
    os_type = execute_command_linux(ssh_client, 'uname').strip()
    logger.info(os_type)

    if os_type == 'Linux':
        jmeter_unzip_path = '/home/apache-jmeter-5.2.1'

        # 检查JMeter是否已经安装
        check_path_command = f'test -d {jmeter_unzip_path} && echo "exists" || echo "not_exists"'
        path_status = execute_command_linux(ssh_client, check_path_command).strip()

        # 传输Jmeter安装包到远程机器
        PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 根目录
        jmeter_local_path = os.path.join(PROJECT_ROOT,
                                         'backend\static\jmeter\\apache-jmeter-5.2.1.tar.gz')
        jmeter_remote_path = '/home/apache-jmeter-5.2.1.tar.gz'

        sftp = ssh_client.open_sftp()
        sftp.put(jmeter_local_path, jmeter_remote_path)
        sftp.close()

        # 解压Jmeter安装包并修改server.rmi.ssl.disable的值
        logger.info("<——————安装jmeter并解压缩——————>")
        execute_command_linux(ssh_client, f'tar -zxvf {jmeter_remote_path} -C /home')
        execute_command_linux(ssh_client,
                              f"sed -i 's/server.rmi.ssl.disable=false/server.rmi.ssl.disable=true/' {jmeter_unzip_path}/bin/jmeter.properties")

        # 正则表达式匹配现有的HEAP设置
        heap_pattern=f': "${{HEAP:="-Xms8g -Xmx28g -XX:MaxMetaspaceSize=1024m"}}"'
        # heap_pattern = re.compile(r':\s*\"\$\{(?:HEAP:=).*?\}\s*"')

        # 新的HEAP设置
        # new_heapSetting = f'HEAP:="-Xms{xms} -Xmx{xmx} -XX'
        new_heapSetting = f': "${{HEAP:="-Xms{xms} -Xmx{xmx} -XX:MaxMetaspaceSize=1024m"}}"'

        # 执行命令
        execute_command_linux(ssh_client,
                              f"sed -i 's/{heap_pattern}/{new_heapSetting}/' {jmeter_unzip_path}/bin/jmeter")

    # 关闭SSH连接
    ssh_client.close()

    return 0

# 传输本地jmeter配置文件到远程机器上
def transfer_jmeter_properties(ip, username, password, xms, xmx):
    PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 根目录
    config_file_local_path = os.path.join(PROJECT_ROOT,
                                     'backend\static\jmeter\jmeter')
    config_file_remote_path = '/home/apache-jmeter-5.2.1/bin/jmeter'

    with open(config_file_local_path, 'r') as file:
        lines = file.readlines()

    new_lines = []
    for line in lines:
        # 使用正则表达式匹配 ${HEAP:=...}
        match = re.match(r': "\$\{HEAP:(.*?)}', line)
        if match:
            print("match")
            heap_values = match.group(1).strip()
            # 构建新的heap_values字符串，保持原有格式不变
            new_heap_values = '="' + '-Xms' + xms + ' -Xmx' + xmx + ' -XX:MaxMetaspaceSize=1024m"'
            new_line = line.replace(heap_values, new_heap_values)
        else:
            new_line = line
        new_lines.append(new_line)

    # 写回修改后的内容到文件
    with open(config_file_local_path, 'w') as file:
        file.writelines(new_lines)

# 传输文件
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_client.connect(ip, username=username, password=password)

    sftp = ssh_client.open_sftp()
    sftp.put(config_file_local_path, config_file_remote_path)
    sftp.close()

    # 关闭SSH连接
    ssh_client.close()
def modify_local_jmeter_properties(properties_file, remote_hosts):
    # 读取文件内容
    with open(properties_file, 'r') as file:
        lines = file.readlines()

    # 修改remote_hosts和server.rmi.ssl.disable的值
    modified_lines = []
    for line in lines:
        if line.startswith('remote_hosts='):
            existing_hosts = line.strip().split('=')[1].split(',')
            if remote_hosts not in existing_hosts:
                line = line.strip() + ',' + remote_hosts + '\n'  # 在原值后面追加指定内容
        elif line.startswith('server.rmi.ssl.disable='):
            line = 'server.rmi.ssl.disable=true' + '\n'
        modified_lines.append(line)

    # 写入修改后的内容到文件
    with open(properties_file, 'w') as file:
        file.writelines(modified_lines)

    logger.info('本地jmeter.properties文件已修改')


def check_jmeter_start(ip, username, password):
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_client.connect(ip, username=username, password=password)

    # 执行命令检查jmeter-server进程是否存在
    output = execute_command_linux(ssh_client, 'ps -ef | grep jmeter-server | grep -v grep')

    if 'jmeter-server' in output:
        logger.info('jmeter-server已启动')
        jmeter_statue = 1
    else:
        logger.info('jmeter-server未启动')
        jmeter_statue = 0

    ssh_client.close()

    return jmeter_statue


def start_jmeter_server_linux(ip, username, password):
    jmeter_server_path = '/home/apache-jmeter-5.2.1/bin'
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_client.connect(ip, username=username, password=password)

    # commands = [
    # "sed -i '/export JAVA_HOME/d' /etc/profile",
    #  'echo "export JAVA_HOME=/home/jdk1.8.0_212" >> /etc/profile',
    # $'echo "export PATH=\\"$PATH:\\$JAVA_HOME/bin\\"" >> /etc/profile',
    # 'source /etc/profile']
    commands = [
        f'cd {jmeter_server_path}',
        'source /etc/profile',
        'nohup ./jmeter-server > jmeter-server.log 2>&1 &']

    # 检查jmeter-server是否已经启动
    # output = execute_command_linux(ssh_client, 'ps -ef | grep jmeter-server | grep -v grep')
    # if './jmeter-server' in output:
        # logger.info('jmeter-server 已启动')
    # else:
        # 检查是否安装了jdk
    if check_jdk_installed(ip, username, password):
        command_string = ';'.join(commands)  # 将所有命令连接成一个字符串
        # 先杀死jmeter-server进程
        execute_command_linux(ssh_client, 'ps -ef | grep jmeter | grep -v grep | awk \'{print $2}\' | xargs kill')
        time.sleep(2)
        execute_command_linux(ssh_client, command_string)  # 启动jmeter-server

        if check_jmeter_start(ip, username, password):
            logger.info("jmeter启动成功")
        else:
            logger.info("jmeter启动失败")
    ssh_client.close()

    return 0


def stop_jmeter_server_Linux(ip, username, password):
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_client.connect(ip, username=username, password=password)

    # 先检查jmeter-server 进程是否存在
    output = execute_command_linux(ssh_client, 'ps -ef | grep jmeter-server | grep -v grep')
    if 'jmeter-server' in output:
        # 执行命令kill所有jmeter-server进程
        execute_command_linux(ssh_client, 'ps -ef | grep jmeter | grep -v grep | awk \'{print $2}\' | xargs kill')
        time.sleep(2)
        # 检查 jmeter-server 进程是否停止成功
        output = execute_command_linux(ssh_client, 'ps -ef | grep jmeter-server | grep -v grep')
        if 'jmeter-server' in output:
            print('停止 jmeter-server 失败')
        else:
            print('停止 jmeter-server 成功')
    else:
        print('jmeter-server 未启动')

    ssh_client.close()


def get_json_content(target_ip,file_path):
    with open(file_path, 'r') as file:
        data = json.load(file)

    for entry in data:
        if entry['ip'] == target_ip:
            return entry
    return None



# 指定远程服务器的IP、用户名和密码
"""
ip = '10.58.20.24'
username = 'root'
password = 'xncs.2023'
remote_hosts = '10.58.20.200:1099'
properties_file = r'D:\apache-jmeter-5.2.1\bin\jmeter.properties'
ssh_connect(ip, username, password)"""
# 检查JDK是否已安装
# check_jdk_installed(ip, username, password)
# 安装jmeter
# install_jmeter(ip, username, password)
# modify_local_jmeter_properties(properties_file,remote_hosts)
# check_jmeter_start(ip, username, password)
# start_jmeter_server_Linux(ip, username, password)
# stop_jmeter_server_Linux(ip, username, password)
# machine_is_enable()
